package com.steven.ourcontest.chat.api

import com.steven.ourcontest.chat.bean.ApplyFriendRes
import com.steven.ourcontest.chat.bean.ChatHistoryRes
import com.steven.ourcontest.chat.bean.ChatOnLineRes
import com.steven.ourcontest.chat.bean.FriendList
import com.steven.ourcontest.chat.bean.UserDetailRes
import com.steven.ourcontest.login.helper.LoginController
import com.steven.ourcontest.net.ApiTransformer
import com.steven.ourcontest.net.EmptyResponse
import com.steven.ourcontest.net.NetConstants
import io.reactivex.Observable
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

class ChatApi private constructor() {

    private val mRetrofit: Retrofit
    private val mApiService: ChatApiService

    companion object {
        const val DEFAULT_TIMEOUT = 5
        val instance: ChatApi by lazy {
            ChatApi()
        }
    }

    init {
        val builder = OkHttpClient.Builder()
        builder.connectTimeout(
            DEFAULT_TIMEOUT.toLong(),
            TimeUnit.SECONDS
        )
        builder.addInterceptor {
            val request = it.request()
            val requestBuilder = request.newBuilder()
            requestBuilder.header("uid", LoginController.userId.toString())
                .header("Accept", "application/json")
                .header("userType", LoginController.userType)
            return@addInterceptor it.proceed(requestBuilder.build())
        }
        mRetrofit = Retrofit.Builder()
            .client(builder.build())
            .baseUrl(NetConstants.CHAT_BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
        mApiService = mRetrofit.create(ChatApiService::class.java)
    }

    fun sendMessageTo(receiveUser: Long, message: String): Observable<EmptyResponse> {
        return mApiService.sendMessageTo(receiveUser, message).compose(ApiTransformer())
    }

    fun query2UserAllMessage(friendId: Long, lastCreateTime: Long): Observable<ChatOnLineRes> {
        return mApiService.query2UserAllMessage(friendId, lastCreateTime).compose(ApiTransformer())
    }

    fun updateMessageStatus(sendUser: Long): Observable<EmptyResponse> {
        return mApiService.updateMessageStatus(sendUser).compose(ApiTransformer())
    }

    fun queryFriends(): Observable<FriendList> {
        return mApiService.queryFriends().compose(ApiTransformer())
    }

    fun sendApplyToFriend(toUser: Long): Observable<EmptyResponse> {
        return mApiService.sendApplyToFriend(toUser).compose(ApiTransformer())
    }

    fun updateApplication(applicantUser: Long,agree: Boolean): Observable<EmptyResponse> {
        return mApiService.updateApplication(applicantUser, agree).compose(ApiTransformer())
    }

    fun queryApplicationToSelf(): Observable<ApplyFriendRes> {
        return mApiService.queryApplicationToSelf().compose(ApiTransformer())
    }

    fun querySelfApplication(): Observable<ApplyFriendRes> {
        return mApiService.querySelfApplication().compose(ApiTransformer())
    }

    fun updateApplicantReadStatus(): Observable<EmptyResponse> {
        return mApiService.updateApplicantReadStatus().compose(ApiTransformer())
    }

    fun deleteFriend(friendId: Long): Observable<EmptyResponse> {
        return mApiService.deleteFriend(friendId).compose(ApiTransformer())
    }

    fun queryUserDetail(uid: Long): Observable<UserDetailRes> {
        return mApiService.queryUserDetail(uid).compose(ApiTransformer())
    }

    fun queryChatFriends(): Observable<ChatHistoryRes> {
        return mApiService.queryChatFriends().compose(ApiTransformer())
    }

    fun addUserBan(uid: Long): Observable<EmptyResponse> {
        return mApiService.addUserBan(uid).compose(ApiTransformer())
    }

    fun deleteUserBan(uid: Long): Observable<EmptyResponse> {
        return mApiService.deleteUserBan(uid).compose(ApiTransformer())
    }
}